	/*******************************************************************************
 * Copyright (c) 2013 Zero Square LLC.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Zero Square LLC. Version 1
 * which accompanies this distribution
 ******************************************************************************/
package com.zsqr.dashboard.controller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import com.zsqr.dashboard.dao.UserDao;
import com.zsqr.dashboard.dao.UserCardDao;
import com.zsqr.dashboard.domain.UserEntity;
import com.zsqr.dashboard.domain.UserCardEntity;
import com.zsqr.dashboard.domain.GatewayRequest;
import com.zsqr.dashboard.domain.GatewayResponse;
import com.zsqr.dashboard.domain.UserCardList;
import com.zsqr.dashboard.services.impl.UserCardServiceImpl;
import com.zsqr.dashboard.services.impl.UserServiceImpl;
import java.util.ArrayList;
import java.util.List;





@Controller
@RequestMapping("/user")
//baseUrl = "http://localhost:8081/zsqr/app/user";
public class UserController {
	
	private Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired 
	UserDao userDao;
	@Autowired
	UserCardDao userCardDao;
	

	
	/**
	 * Give list of cards for a user
	 * @param userName
	 * @return XML/JSON having list of card
	 * //baseUrl = "http://localhost:8081/zsqr/app/user/cardlist
	 */
	
	@RequestMapping(value = "cardlist/{username:.+}" , method=RequestMethod.GET)
			//, headers="Accept=application/xml,application/jason,text/html,application/html"
		//,produces = {"application/json", "application/xml" })
    @ResponseBody
    UserCardList getCardList(@PathVariable("username") String userName) {
    //UserCardServiceImpl getCardList(@PathVariable("username") String userName) {
		logger.debug("Provider has received request to get list of all card for user: "
				   + userName);
		UserCardServiceImpl cardList = new UserCardServiceImpl();
		cardList.setUserCardDao(userCardDao);
		UserCardList listCard = new UserCardList();
		listCard.setCardInfo(cardList.getUserCard(userName));
        return listCard;
    }
	
	//Only to test RestClientController..
	@RequestMapping(value = "loadcard/" , method=RequestMethod.POST)
	@ResponseBody
	UserCardEntity getWSCard(@RequestBody UserEntity userEntity) {
		logger.debug("Provider has received request to get list of all card for user: "
		   + userEntity);
		String ccNum = "xxxxxxxxxxxx6465";
		UserCardEntity ucardEntity = userCardDao.getCardByCardNumber(ccNum);
		if(ucardEntity == null) 
		{
			throw new NotFoundException();
        }
		return ucardEntity;
		
	}
	
	//Only to test GatewayRequest object values
	@RequestMapping(value = "greq/{username:.+}" , method=RequestMethod.GET)
	@ResponseBody
	GatewayRequest getreq(@PathVariable("username") String userName) {
		logger.debug("Provider has received request to get GatewayRequest: "
		   + userName);
		GatewayRequest gatewayRequest = new GatewayRequest();
		return gatewayRequest;
		
	}
	
	//Only to test GatewayResposne object values
	@RequestMapping(value = "gres/{username:.+}" , method=RequestMethod.GET)
	@ResponseBody
	GatewayResponse getres(@PathVariable("username") String userName) {
		logger.debug("Provider has received request to get GatewayResponse: "
		   + userName);
		GatewayResponse gatewayResponse = new GatewayResponse();
		return gatewayResponse;
		
	}
	
	
	
	@RequestMapping(value = "createcardlist/{username:.+}" , method=RequestMethod.GET)
			//, headers="Accept=application/xml,application/jason,text/html,application/html"
		//,produces = {"application/json", "application/xml" })
		@ResponseBody
		void createCardList(@RequestBody UserCardList uCardList ) {
		//UserCardServiceImpl getCardList(@PathVariable("username") String userName) {
			logger.debug("Provider has given a  request to add list of all card for user: "
					   + uCardList.getCardInfo().getClass());
			UserCardServiceImpl cardList = new UserCardServiceImpl();
			cardList.setUserCardDao(userCardDao);
			//cardList.setUserCardList(uCardList.getUserCardList());
			boolean bRet = cardList.saveCardList(uCardList.getCardInfo());
			//BooleanValue retVal = new BooleanValue();
			//retVal.setReturnVal(bRet);
			//return retVal;
		}
		

		
		 @RequestMapping(value = "addCard/" , method=RequestMethod.POST)
		   @ResponseStatus(HttpStatus.OK)
		    void AddCard(@RequestBody UserCardEntity userCardEntity ) {
			   logger.debug("Provider has received request to create user with UserName: "
					   + userCardEntity.getCardNumber());
			   UserCardServiceImpl userCardData = new UserCardServiceImpl();
			   userCardData.setUserCardDao(userCardDao);
			   boolean bRet = userCardData.AddCard(userCardEntity);
			   //BooleanValue retVal = new BooleanValue();
			   //retVal.setReturnVal(bRet);
			  // return bRet;
		 }
		 
		 
	
	/**
	 * Register user to DB
	 * @param JSON/XML with user details , method=RequestMethod.POST
	 * @return HttpStatus.OK if user registration completed successfully
	 */
	
	   @RequestMapping(value = "createuser/" , method=RequestMethod.POST)
	   @ResponseStatus(HttpStatus.OK)
	    void createUser(@RequestBody UserEntity userEntity ) {
		   logger.debug("Provider has received request to create user with UserName: "
				   + userEntity.getUserName());
		   UserServiceImpl userData = new UserServiceImpl();
	    	userData.setUserDao(userDao);
			userData.createUser(userEntity);	           
	    }
	   
	   /**
		 * get card detailsm from  DB
		 * @param JSON/XML with card details , RequestMethod.GET
		 * @return card details
		 */
	    
	   @RequestMapping(value = "getCardDetails/{cardnumber:.+}" , method=RequestMethod.GET)
	    @ResponseBody
	    UserCardEntity getCard(@PathVariable("cardnumber") String cardnumber) {
			logger.debug("Provider has received request to load user for CardNumber: "
					   + cardnumber);
			UserCardEntity usercardEntity = userCardDao.getCardByCardNumber(cardnumber);
			if(usercardEntity == null) 
			{
				throw new NotFoundException();
            }
			return usercardEntity;
		}
       
	   /**
		 * get card detailsm from  DB
		 * @param JSON/XML with card details , RequestMethod.GET
		 * delete card details
		 */
	   
	   @RequestMapping(value = "deleteCard/{cardnumber:.+}" , method=RequestMethod.GET)
	   @ResponseStatus(HttpStatus.OK)
	    void delCard(@PathVariable("cardnumber") String cardnumber) {
			logger.debug("Provider has received request to load user for CardNumber: "
					   + cardnumber);
			UserCardServiceImpl userCardData = new UserCardServiceImpl();
		    userCardData.setUserCardDao(userCardDao);
		    boolean bRet = userCardData.delCard(cardnumber);
		}
    /**
	 * Update user details in DB
	 * @param JSON/XML with user details , RequestMethod.PUT
	 * @return HttpStatus.OK if user update completed successfully
	 */
  
    @RequestMapping(value = "updateuser/" , method=RequestMethod.PUT)
    @ResponseBody
    @ResponseStatus(HttpStatus.OK)
    void updateUser(@RequestBody UserEntity userEntity ) {
    	//Create Dao method updateUser() to update user info in DB    
    	logger.debug("Provider has received request to edit person with UserName: "
   			 + userEntity.getUserName());
		UserServiceImpl userData = new UserServiceImpl();
    	userData.setUserDao(userDao);
    	userData.updateUser(userEntity);
           
    }
	
	/**
	 * Login user to application by getting user info from DB
	 * @param userName
	 * @return XML/JSON having user details
	 * http://localhost:8081/zsqr/app/user/loaduser/test@test.com
	 */
	@RequestMapping(value = "loaduser/{userName:.+}" , method=RequestMethod.GET)
    @ResponseBody
    UserEntity getUser(@PathVariable("userName") String userName) {
		logger.debug("Provider has received request to load user for UserName: "
				   + userName);
		UserEntity userEntity = userDao.loadUserByUserName(userName);
		if(userEntity == null) 
			{
				throw new NotFoundException();
            }
		return userEntity;
	}
	
	/**
	 * Validate if user name available to use
	 * @param userName
	 * @return true if user name available
	 */
	
	@RequestMapping(value = "checkuser/{username:.+}" , method=RequestMethod.GET)
    @ResponseBody
    boolean getUserName(@PathVariable("username") String userName) {
		logger.debug("Provider has received request to check availabilty of  UserName: "
				   + userName);
		boolean isUserAvailable = userDao.checkAvailable(userName);
		return isUserAvailable;
	}
	
	/**
	 * Validate if user name available to use
	 * @param userName
	 * @return true if user name available
	 */
	
	@RequestMapping(value = "validatelogin/" , method=RequestMethod.POST)
	 @ResponseBody
	    boolean validateLogin(@RequestBody UserEntity userEntity ) {
	    	UserServiceImpl userData = new UserServiceImpl();
	    	userData.setUserDao(userDao);
			if(userData.validateLogin(userEntity))
			{
				return true;
			}
			return false;
	    }
   
	
	/**
	 * Delete user from DB
	 * @param userName
	 * @return true if user got removed from DB
	 */
	
	@RequestMapping(value = "deleteuser/{username:.+}" , method=RequestMethod.DELETE)
    @ResponseBody
    boolean deleteUser(@PathVariable("username") String userName) {
		//Write a DAO method call deleteUserByUserName() which will delete user fields when get DELETE request
		logger.debug("Provider has received request to delete UserName: "
				   + userName);
		UserEntity userEntity = userDao.loadUserByUserName(userName);
		
		if(userEntity == null) 
		{
			throw new NotFoundException();
        }
		userDao.delete(userEntity);
		return true;
	}
	
	/**
	 * Handle not found exception 
	 * @param NotFoundException
	 * @return HttpStatus.NOT_FOUND with reason
	 */
	@ExceptionHandler(NotFoundException.class)
    @ResponseStatus(value=HttpStatus.NOT_FOUND, reason="User not found")
    void handleNotFound(NotFoundException exc) {    
		logger.debug("User Not found and Exception is: "
				   + exc.getMessage());
    }    
    class NotFoundException extends RuntimeException {
            private static final long serialVersionUID = 1L;                
    }
}
